package com.example.vueblog.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.json.JSONUtil;
import com.example.vueblog.common.RedisConstants;
import com.example.vueblog.common.execption.*;
import com.example.vueblog.common.utils.JwtTokenUtil;
import com.example.vueblog.common.utils.RedisUtils;
import com.example.vueblog.entity.UserInfo;
import com.example.vueblog.entity.security.LoginBody;
import com.example.vueblog.entity.security.SelfUserDetails;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import org.springframework.util.FastByteArrayOutputStream;
import sun.misc.MessageUtils;

import java.util.Map;
import java.util.Optional;

/**
 * @author yushunshun
 * @date 2022/7/18 23:56
 */
@Service
public class LoginService {

    @Autowired
    RedisUtils redisUtils;
    @Autowired
    AuthenticationManager authenticationManager;

    /**
     * 登录
     *
     * @param loginBody 请求信息
     * @return
     */
    public UserInfo login(LoginBody loginBody) {
        String uuid = loginBody.getUuid();
        String key = RedisConstants.VERIFY_CODE + uuid;
        //获取redis 用户生成的验证码
        String code = redisUtils.get(key);
        //查询不到验证码提示错误
        if (code == null) throw new LoginVerifyException();
        //比较验证码
        if (!code.equalsIgnoreCase(loginBody.getCode())) throw new CaptchaException();

        //用户验证
        Authentication authentication = null;
        try {
            authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginBody.getUsername(), loginBody.getPassword()));
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                //AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            } else {
                //AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                throw new ServiceException();
            }
        }

        SelfUserDetails userDetails = (SelfUserDetails) authentication.getPrincipal();

        String token = JwtTokenUtil.generateToken(userDetails.getUsername(), JSONUtil.toBean(JSONUtil.toJsonStr(userDetails), new TypeReference<Map<String, Object>>() {
        }, true));

        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(userDetails,userInfo);
        userInfo.setToken("Bearer "+token);
        return userInfo;
    }
}
